package ncrnadb.ncinetview.internal.cy;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import ncrnadb.ncinetview.internal.owrapper.ORDB;
import ncrnadb.ncinetview.internal.owrapper.RID;

import org.cytoscape.model.CyColumn;
import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyNode;
import org.cytoscape.model.CyRow;

import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientVertex;


public class CyUtils {

	

	public static String ORIDNodeColumnName = "ncrnadb-ORID";
	public static String ORIDEdgeColumnName = "ncrnadb-ORID";
	
	
	public static String DefaultTypeColumnName = "ncrnadb-type";
	public static String DefaultAliasesColumnName = "ncrnadb-aliases";
	
	public static void addORIDColumns(CyNetwork net){
		if( net.getDefaultNodeTable().getColumn(ORIDNodeColumnName) == null){
			net.getDefaultNodeTable().createListColumn(ORIDNodeColumnName, String.class, false);
		}

		if(net.getDefaultEdgeTable().getColumn(ORIDEdgeColumnName) == null){
			net.getDefaultEdgeTable().createColumn(ORIDEdgeColumnName, String.class, false);
		}
		
		
		String[] ef = {"level", "pubmed", "support", "source"};
		for(String f: ef){
			if(net.getDefaultEdgeTable().getColumn(f) == null){
				net.getDefaultEdgeTable().createColumn(f, String.class, false);
			}
		}
	}
	
	
	public static void addDefaultColumns(CyNetwork net){
		if( net.getDefaultNodeTable().getColumn(DefaultTypeColumnName) == null){
			net.getDefaultNodeTable().createColumn(DefaultTypeColumnName, String.class, false);
		}
		if( net.getDefaultNodeTable().getColumn(DefaultAliasesColumnName) == null){
			net.getDefaultNodeTable().createListColumn(DefaultAliasesColumnName, String.class, false);
		}
	}
	
	public static CyColumn createTypeColumn(CyNetwork net){
		String name = DefaultTypeColumnName;
		if(net.getDefaultNodeTable().getColumn(name) == null){
			net.getDefaultNodeTable().createColumn(name, String.class, false);
		}
		else{
			int i=0;
			while(true){
				name = DefaultTypeColumnName +"_"+i;
				if(net.getDefaultNodeTable().getColumn(name) == null){
					net.getDefaultNodeTable().createColumn(name, String.class, false);
					break;
				}			
				i++;
			}
		}
		
		return net.getDefaultNodeTable().getColumn(name);
	}
	
	
	
	public static CyColumn createAliasesColumn(CyNetwork net){
		String name = DefaultAliasesColumnName;
		if(net.getDefaultNodeTable().getColumn(name) == null){
			net.getDefaultNodeTable().createColumn(name, String.class, false);
		}
		else{
			int i=0;
			while(true){
				name = DefaultAliasesColumnName +"_"+i;
				if(net.getDefaultNodeTable().getColumn(name) == null){
					net.getDefaultNodeTable().createColumn(name, String.class, false);
					break;
				}			
				i++;
			}
		}
		
		return net.getDefaultNodeTable().getColumn(name);
	}
	
	
	public static Collection<String> getStringValues(CyRow row, CyColumn column){
		Collection<String> values = null;
		if(column.getType() == String.class){
			//it's a String cycolumn
			if(row.get(column.getName(), String.class) != null){
				values = new LinkedList<String>();
				values.add(row.get(column.getName(), String.class));
			}
		}
		else{
			//it's a list String cycolumn
			if(row.getList(column.getName(), String.class) != null)
				values = row.getList(column.getName(), String.class);
		}
		return values;
	}
	
	
	
	public static CyNode addEntityToNetwork( ORDB ordb, Vertex eVertex, CyNetwork network, CyColumn typeColumn, CyColumn aliasesColumn){
		
		//create cynode
		CyNode cnode = network.addNode();
		
		//get its cyrow
		CyRow crow = network.getDefaultNodeTable().getRow(cnode.getSUID());
		
		//set its RID in cyrow
		List<String> orid = new LinkedList<String>();
		orid.add(eVertex.getId().toString());
		crow.set(ORIDNodeColumnName, orid);
		
		//set its type in cyrow
		crow.set(typeColumn.getName(), ordb.oRBioEntityClusters.get((((OrientVertex)eVertex).getIdentity().getClusterId())).type);
		
		
		String name = null;
		//get all its aliases by RIDs		
		List<String> avss = new LinkedList<String>();
		Collection<RID> rids = ordb.getRIDs(eVertex);
		for(RID rid : rids){
			avss.add(rid.toString());
			if(name == null){
				name = rid.id;
			}
		}
		if(name == null){
			name = eVertex.getId().toString();
		}
		
		//set its alias (by RIDs) in cyrow
		if(aliasesColumn.getType() == String.class){
			crow.set(aliasesColumn.getName(), avss.get(0));
		}
		else{
			crow.set(aliasesColumn.getName(), avss);
		}
		
		crow.set("name", name);
		
		return cnode;
	}
	
	public static CyNode addEntityToNetwork(
			Collection<String> aliases,
			Collection<Vertex> ents,
			ORDB ordb,  
			CyNetwork network, 
			CyColumn typeColumn, 
			CyColumn aliasesColumn){
		
		//create cynode
		CyNode cnode = network.addNode();
		//get its cyrow
		CyRow crow = network.getDefaultNodeTable().getRow(cnode.getSUID());
		
		crow.set(typeColumn.getName(), "");
		
		String name = null;
		
		List<String> aliasesField = new LinkedList<String>();
		for(String s : aliases){
			aliasesField.add(s);
			if(name == null){
				name = s;
			}
		}
		if(aliasesColumn.getType() == String.class){
			crow.set(aliasesColumn.getName(), aliasesField.get(0));
		}
		else{
			crow.set(aliasesColumn.getName(), aliasesField);
		}
		
		
		List<String> ridsField = new LinkedList<String>();
		for(Vertex v : ents){
			ridsField.add(v.getId().toString());
			if(name == null){
				name = v.getId().toString();
			}
		}
		crow.set(ORIDNodeColumnName, ridsField);
		
		if(name == null)
			name = "";
		crow.set("name", name);
		
		return cnode;
	}
	
}
